﻿using IntoTheVoid.Models;
using IntoTheVoid.Units;
using IntoTheVoid.ViewModels;
using IntoTheVoid.Views;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace IntoTheVoid.State
{
	public class OpenGameState : State
	{
		private Process externalProcess;
		private readonly string DIC_NAME = @"IntoTheVoid\";
		private readonly string EXE_NAME = @"IntoTheVoid.exe";
		private bool bForOpenCheck = false;

		public OpenGameState(StateContext context)
		{
			LogHelper.Info(" Check switch Enter  OpenGameState");

			if (!CheckIsOpened())
			{
				LogHelper.Info(" Check switch Enter  CheckIsOpened");
				buttonContent = ("开始游戏");
				buttonEnabla = true;
				Context = context;
				Context.OnButtonStateArgs(new ButtonStateChangeEventArgs(buttonContent, buttonEnabla, false, true, "StartDownloadButton"));
			}
			else
			{
				LogHelper.Info(" Check switch Enter  CheckIsOpened");
				buttonContent = ("  游戏中");
				buttonEnabla = false;
				Context = context;
				Context.OnButtonStateArgs(new ButtonStateChangeEventArgs(buttonContent, buttonEnabla, false, false, "StartDownloadButtonGray"));
			}
			LogHelper.Info(" Check switch Exit  CheckIsOpened");

		}
		public override void Start(StateContext download)
		{
			var gameDownlaodConifgModel = GameDownloadConfigModel.Instance;
			gameDownlaodConifgModel.DownLoadConfigCompleted += OpenGameUpdateCheck;
			gameDownlaodConifgModel.SendStartConfigMessage(BaseInfoContentModel.Instance.GetValue<string>("version", ""));
			bForOpenCheck = true;
			KillStartedGame();

		}
		bool CheckIsOpened()
		{
			foreach (Process p in Process.GetProcesses())
			{
				if (p.ProcessName.Contains("IntoTheVoid"))
				{
					string fileName;
					try
					{
						fileName = p.MainModule?.FileName;
					}
					catch
					{
						// 无权限访问该进程的MainModule，跳过
						continue;
					}

					var defaultPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Game");
					var path = BaseInfoContentModel.Instance.GetValue<string>("gameInstallPath", defaultPath);
					var expectedPath = Path.Combine(path, "IntoTheVoid", "IntoTheVoid.exe");

					if (fileName != null && fileName.Equals(expectedPath, StringComparison.OrdinalIgnoreCase))
					{
						if (externalProcess == null)
						{
							externalProcess = p;
						}
						return true;
					}
				}
			}
			return false;
		}
		private void KillStartedGame()
		{
			if (CheckIsOpened())
			{
				LogHelper.Warn("Close Game exe :" + externalProcess.MainModule.FileName);
				if (externalProcess != null)
				{
					externalProcess.Kill();
					externalProcess = null;
				}
			}
		}
		private void OpenGameUpdateCheck(object sender, GameDownloadConfigEventArgs e)
		{
			if (!bForOpenCheck)
			{
				return;
			}
			bForOpenCheck = false;
			var localVersion = BaseInfoContentModel.Instance.GetValue<string>("version", "");
			var info = GameDownloadConfigModel.Instance.DownLoadInfo;
			// 后台强制更新
			if (info.LauncherForceUpdate)
			{
				// 需要更新
				if (!Common.CheckLauncherVersion(info.LauncherLatest))
				{
					Action confirmAction = () =>
					{
						Common.OpenLauncherUpdate(info.LauncherLink);
					};
					Context.OnTipsStateArgs(new TipsEventArgs(string.Format("启动器更新：修复了部分问题"), confirmAction, () => Environment.Exit(0)));
					return;
				}
			}
			if (info.OpenedLatest != localVersion)					
			{
				LogHelper.Warn("Open Game Update Check,Need Update New Version,Currrent Version :" + localVersion + "New Version : " + info.OpenedLatest);
				Context.OnTipsStateArgs(new TipsEventArgs("需要更新游戏版本才可进入"));
				Context.StateType = StateType.NeedUpdate;
				Context.CurState = new UpdateState(Context);
			}					
			else if (info.UnderMaintenance)		
			{
				Context.OnTipsStateArgs(new TipsEventArgs("系统维护中，请稍后再试\n" + info.MaintenanceTip));
				return;
			}
			else
			{
				LogHelper.Info("Open Game");
				var defaultPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Game");
				var path = BaseInfoContentModel.Instance.GetValue<string>("gameInstallPath", defaultPath);
				StartExternalProgram(path);
			}
		}

		private void StartExternalProgram(string path)
		{
			string programPath = Path.Combine(path, DIC_NAME, EXE_NAME);

			if (System.IO.File.Exists(programPath))
			{
				externalProcess = new Process();
				externalProcess.StartInfo.FileName = programPath;
				externalProcess.EnableRaisingEvents = true;
				externalProcess.Exited += ExternalProcess_Exited;
				Context.StateType = StateType.Opening;
				buttonEnabla = false;
				buttonContent = "  游戏中";
				Context.OnButtonStateArgs(new ButtonStateChangeEventArgs(buttonContent, buttonEnabla, false, false, "StartDownloadButtonGray"));
				externalProcess.Start();

				// 开启CE检测
				CheatEngineDetector.Instance.Start(externalProcess.Id);

				// 最小化启动器
				Context.OnWindowStateeArgs(new MainWindowVisableArgs(false, WindowState.Minimized));
			}
			else
			{
				// 错误处理
				Context.OnTipsStateArgs(new TipsEventArgs("未找到相关引用"));
				LogHelper.Error("Open Game Error: File Not Exist : " + programPath);
				BaseInfoContentModel.Instance.DeleteFile();
				// 删除配置文件重新下载
				Context.StateType = StateType.CheckingUpdate;
				Context.CurState = new FirstCheckState(Context);
				Context.CurState.Start(Context);
			}
		}

		private void ExternalProcess_Exited(object sender, EventArgs e)
		{
			App.Current.Dispatcher.Invoke((Action)delegate ()
			{
				var autoOpenGameLauncherSign = BaseInfoContentModel.Instance.GetValue<int>("autoOpenGameLauncher", 1);
				if (autoOpenGameLauncherSign == 1)
				{
					// 显示启动器
					Context.OnWindowStateeArgs(new MainWindowVisableArgs(true, WindowState.Normal));

				}
			});
			Context.StateType = StateType.CanOpenGame;
			Context.CurState = new OpenGameState(Context);
			externalProcess = null;
			LogHelper.Info("External program has exited");

			// 关闭CE检测
			CheatEngineDetector.Instance.Stop();
			Common.DeleteReportFile();
		}
	}
}
